package com.slz3.business.frame.aop;


import com.slz3.business.frame.annotation.ConfigDomain;
import com.slz3.business.frame.module.DomainEntity;
import com.slz3.business.frame.module.Repositorys;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.ApplicationContext;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.Optional;

import static com.slz3.business.frame.sync.SyncPGToRedis.sync;

/**
 * redis sync
 * ConfigDomain:MenuName:DataJsonStr:${uuid}
 * ConfigDomain:ModuleName:MenuName:UuidList
 * IdMapUuid:Business:${incrementId}
 * UuidSet:MenuName
 */
@Aspect
@Component
@Slf4j
public class ControllerAop {

    @Resource
    private ApplicationContext context;

    @Pointcut("execution(public * com.slz3.business.module.*.*.steward.*Controller.*(..))")
    public void pointcut() {
    }

    @After("pointcut() && args(request, domainEntity)")
    public void after(JoinPoint pjp, ServerRequest request, DomainEntity domainEntity) {
        try {
            log.info("start ControllerAop After: {}", pjp.getSignature().getName());
            if (request == null || domainEntity == null) {
                log.warn("获取不到request请求 或 实体类");
                return;
            }
            String methodName = request.method().name();
            if (!"POST".equalsIgnoreCase(methodName) && !"PUT".equalsIgnoreCase(methodName)) {
                log.warn("请求方法不是POST或者PUT请求");
                return;
            }

            ConfigDomain configDomain = Optional.ofNullable(
                    domainEntity.getClass().getAnnotation(ConfigDomain.class)
            ).orElse(
                    domainEntity.getClass().getSuperclass().getAnnotation(ConfigDomain.class)
            );
            if (configDomain == null) {
                log.warn("该实体类 {} 不是配置实体类", domainEntity.getClass());
                return;
            }
            JpaRepository repository = context.getBean(configDomain.repositoryClass());
            if (repository == null) {
                log.warn("获取不到该实体类 {} 配置的JpaRepository的实例,请重新配置！", domainEntity.getClass());
                return;
            }
            /** sync **/
            sync(repository, domainEntity);
            //
            log.info("end ControllerAop After: {}", pjp.getSignature().getName());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("ControllerAop After error : {}", e);
        }
    }

    public static void main(String[] args) throws NoSuchFieldException {
        Field sysMenu = Repositorys.class.getDeclaredField("sysMenu");
        System.out.println(sysMenu);
    }
}
